【PHP】クラスの継承(extends) - 既存クラスの定義を引き継ぐクラス
クラスには『クラスの継承』と呼ぶ仕組みがあります。
クラスの継承を使うことで、既存クラスの定義を引き継ぐクラスを定義することができます。
ここでは、継承について解説します。
検証環境
クラスの継承
クラスの継承は“クラス定義において、既存クラスの定義を引き継ぐこと”です。
スーパークラス
クラスの継承において、継承元をスーパークラスまたは親クラスと呼びます。
サブクラス
クラスの継承において、継承先をサブクラスまたは子クラスと呼びます。
サブクラスはスーパークラスのフィールドやメソッド等を使用できます。
基本構文
クラスの継承はextends
キーワードを使用します。
class サブクラス名 extends スーパークラス名 {
// 定義 etc ...
}
通常のクラス定義に加えて、extends
キーワードとスーパークラス名を記述します。
サンプル
<?php
// 人間クラス
class Person {
// 名前
public $name;
// コンストラクタ
public function __construct( $name ) {
$this->name = $name;
}
// あいさつ
public function greeting() {
echo "Hey!\n";
echo "My name is ". $this->name . ".\n";
}
}
// 教師クラス
___ih_hl_start
class Teacher extends Person {
}
___ih_hl_end
___ih_hl_start
$teacher = new Teacher('TANAKA');
___ih_hl_end
var_dump($teacher);
___ih_hl_start
$teacher->greeting();
___ih_hl_end
?>
$ php sample.php
object(Teacher)#1 (1) {
["name"]=>
string(6) "TANAKA"
}
Hey!
My name is TANAKA.
23〜25行目はPerson
クラスを継承したTeacher
クラスの定義です。
Teacher
クラスはフィールドやメソッドの定義がありませんが、スーパークラス(Person
クラス)の$name
フィールドやコンストラクタ、greeting
メソッドの定義を引き継ぎます。
引き継いだ定義はTeacher
クラスから使用でき、実際に27行目ではTeacher
クラスに引数があるコンストラクタは未定義ですが、引数を取ってオブジェクトを生成しており、この時にPerson
クラスのコンストラクタが呼び出されています。
また、その後のvar_dump
関数の出力から、そのオブジェクトはTeacher
クラスであることが分かります。
31行目ではTeacher
クラスのオブジェクトに対して、greeting
メソッドを呼び出していますが、実行結果からPerson
クラスに定義したgreeting
メソッドの処理が実行されており、$name
フィールドにはコンストラクタの引数に渡した'TANAKA'
が記憶されていることが分かります。
このようにサブクラスはスーパークラスの定義を引き継ぐことが可能です。
クラスの拡張
サブクラスは新たにフィールドやメソッド等の定義を追加し、拡張することができます。
例えば次のコードは上記サンプルのTeacher
クラスに新しく定義を追加したコードです。
<?php
// 人間クラス
class Person {
// 名前
public $name;
// コンストラクタ
public function __construct( $name ) {
$this->name = $name;
}
// あいさつ
public function greeting() {
echo "Hey!\n";
echo "My name is ". $this->name . ".\n";
}
}
// 教師クラス
class Teacher extends Person {
// 担当科目
___ih_diff_start
+ public $subject = 'Programming';
___ih_diff_end
// 授業
___ih_diff_start
+ public function lesson() {
+ echo $this->subject . ' : ' . $this->name;
+ }
___ih_diff_end
}
$teacher = new Teacher('TANAKA');
___ih_diff_start
-var_dump($teacher);
___ih_diff_end
___ih_diff_start
-$teacher->greeting();
+$teacher->lesson();
___ih_diff_end
?>
$ php sample.php
Programming : TANAKA
※ 行先頭にマイナス-
があるコードは削除という意味です。
26行目の$subject
フィールドと29〜31行目のlesson
メソッドが新しく追加(拡張)した定義です。
Person
クラスを継承するため、lesson
メソッドの処理で、$name
に擬似変数$this
を経由してアクセスできます。
38行目でlesson
メソッドを呼び出しており、実行結果から正常に処理が行われていることが分かります。
このように、継承では既存クラスを引き継ぎ、新しくフィールドやメソッドを追加することで拡張したクラスを定義することが可能です。
アクセス修飾子の制限
アクセス修飾子がprivate
なプロパティ(フィールドやメソッド)は定義を引き継ぐことができません。
アクセス修飾子については別途解説しますが、ここでは、public
またはprotected
なプロパティのみ定義を引き継げることを覚えておきましょう。
演習問題
次の実行結果になるプログラムを作成してください。
なお、下記条件を満たすものとします。
- 下記表の3つのクラスを作成する
- 実行結果になるように各クラスのインスタンスを使う
クラス | 英記 | 継承元 | フィールド | メソッド |
---|---|---|---|---|
乗り物クラス | Vehicle |
なし | ・$distance (移動距離)
※ 初期値は0 |
・move()
→ "移動します。" を出力し、$distance の値を20加算する。
・ display_distance()
→ $distance の値を出力 |
車クラス | Car |
Vehicle |
なし | ・run()
→ "走行します。" を出力し、$distance の値を50加算する。 |
飛行機クラス | Airplane |
Vehicle |
なし | ・fly()
→ "飛行します。" を出力し、$distance の値を50加算する。 |
===== 乗り物クラスのインスタンス =====
移動します。
移動距離 : 20km
===== 車クラスのインスタンス =====
走行します。
走行します。
移動距離 : 100km
===== 飛行機クラスのインスタンス =====
飛行します。
飛行します。
飛行します。
移動距離 : 2400km
次の実行結果になるプログラムを作成してください。
なお、下記条件を満たすものとします。
- 下記表の3つのクラスを作成する
- 実行結果になるように各クラスのインスタンスを使う
クラス | 英記 | 継承元 | フィールド | メソッド |
---|---|---|---|---|
チケットクラス | Ticket |
なし | ・$price (料金) |
・display_price()
→ $ の値を出力 |
ライブチケット | LiveTicket |
Ticket |
・$place (場所) |
・info()
→ 場所と料金を出力 ※ 料金の出力は display_price() を使う |
ライブ配信チケット | LiveStreamingTicket |
Ticket |
・$url (URL) |
・info()
→ URLと料金を出力 ※ 料金の出力は display_price() を使う |
===== ライブチケットクラスのインスタンス =====
場所 : ライブハウス
料金 : 8000円
===== ライブ配信クラスのインスタンス =====
URL : https://it-hack.net/live-streaming
料金 : 3000円